<?php
/**
 * 
 * @author Tomasz Ulanowski <tomasz@ulanowski.info> 
 *
 */
class MyZendX_Controller_Action_Helper_Uploadify extends Zend_Controller_Action_Helper_Abstract
{
	/**
	 * @var Zend_Log
	 */
	protected $_logger;

	/**
	 * @var MyZendX_File_Transfer_Adapter_Uploadify
	 */
	protected $_transferAdapter;

	/**
	 * @var array
	 */
	protected $_options;
	
	/**
	 * @return MyZendX_Controller_Action_Helper_Uploadify
	 */
	public function direct($options = array())
	{
		$this->setOptions($options);
		return $this;
	}

	/**
	 * @param Zend_Config|array $options
	 * @return MyZendX_Controller_Action_Helper_Uploadify
	 */
	public function setOptions($options)
	{
		if ($options instanceof Zend_Config) {
			$options = $options->toArray();
		}
		foreach($options as $key => $value) {
			$method = 'set' . ucfirst($key);
			if (method_exists($this, $method)) {
				$this->$method($value);
			}
			else {
				$this->_options[$key] = $value;
			}
		}
		return $this;
	}
	
	/**
	 * Upload
	 */
	public function upload()
	{
		$controller	= $this->getActionController();
		$request	= $this->getRequest();
		$view		= $controller->view;
		
		$controller->getHelper('ViewRenderer')->setNoRender();
		
		$adapter = $this->getTransferAdapter()->getBackendTransferAdapter();
		$origFileInfo = $adapter->getFileInfo();
		
		$result = $adapter->receive();
		if ( $result === true ) {
			$fileinfo = $adapter->getFileInfo();
	
			$files = array();
			foreach( $fileinfo as $key => $file ) {
				$f = array(
					'name' 		=> $file['name'],
					'origName' 	=> $origFileInfo[$key]['name'],
					'isImage' 	=> self::isImage($file['tmp_name']),
					'type' 		=> $file['type'],
					'size' 		=> $file['size'],
					'sizeHuman'	=> self::toByteString($file['size']) 
				);
				$files[] = $f;
				$this->_log(sprintf('File %s uploaded to %s.', $f['origName'], $file['tmp_name']), Zend_Log::INFO);
			}
			
			print $view->JSon(array('uploaded' => $files));
		}
		else {
			$this->_log($adapter->getMessages(), Zend_Log::WARN);
			
			//$this->getResponse()->setHttpResponseCode(415);
			print $view->JSon(array('errors' => $adapter->getMessages()));
		}
		
	}
	
	/**
	 * Preview
	 */
	public function preview()
	{
		$request = $this->getRequest();
		$file = $request->getParam('file');
		$transferAdapter = $this->getTransferAdapter();
		$file = $transferAdapter->findTmpUploadedFile($file);
		if (null === $file) {	
			throw new Zend_Controller_Action_Exception('File not found', 404);
		}
		$this->getActionController()->getHelper('ViewRenderer')->setNoRender();
		
		if ($this->isImage($file)) {
			$this->getResponse()->setHeader('Content-Type', self::getMimeType($file));
			// make thumbnail
			$im = new Imagick($file);
			$im->thumbnailimage($request->getParam('width', 200), $request->getParam('height', 200), true);
			echo $im;
		}
	}	
	
	/**
	 * @param string $path
	 * @return boolean
	 */
	public static function isImage($file)
	{
		$isImageValidator = new Zend_Validate_File_IsImage();
		return $isImageValidator->isValid($file);
	} 	
	
	/**
	 * @param string $file
	 * @return boolean
	 */
	public static function getMimeType($file)
	{
		// detect mime type
		$finfo = finfo_open(FILEINFO_MIME_TYPE);
		$mime = finfo_file($finfo, $file);
		finfo_close($finfo);
		return $mime;
	}
	
	/**
	 * @param Zend_Log
	 * @return MyZendX_Controller_Action_Helper_Uploadify
	 */
	public function setLogger(Zend_Log $logger)
	{
		$this->_logger = $logger;
		return $this;
	}
	
	/**
	 * @return Zend_Log|null
	 */
	public function getLogger()
	{
		return $this->_logger;		
	}
	
	/**
	 * @return MyZendX_File_Transfer_Adapter_Uploadify
	 */
	public function getTransferAdapter()
	{
		if (null === $this->_transferAdapter) {
			$this->_transferAdapter = new MyZendX_File_Transfer_Adapter_Uploadify();
		}
		return $this->_transferAdapter;
	}
	
	/**
	 * Log a message at a priority
	 *
	 * @param  string   $message   Message to log
	 * @param  integer  $priority  Priority of message
	 * @param  mixed    $extras    Extra information to log in event
	 * @return void
	 * @throws Zend_Log_Exception
	 */
	protected function _log($message, $priority, $extras = null)
	{
		$logger = $this->getLogger();
		if ($logger instanceof Zend_Log) {
			$logger->log($message, $priority, $extras = null);
		}
	}
	
	/**
	 * Returns the formatted size
	 *
	 * @param  integer $size
	 * @return string
	 */
	public static function toByteString($size)
	{
		$sizes = array('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
		for ($i=0; $size >= 1024 && $i < 9; $i++) {
			$size /= 1024;
		}

		return round($size, 2) . $sizes[$i];
	}
}